package com.yihukurama.sysbase.sysservice.impl;

import com.yihukurama.base.app.cache.RedisUtils;
import com.yihukurama.base.app.constant.Constant;
import com.yihukurama.base.app.exception.TipsException;
import com.yihukurama.base.app.security.AbstractJwtTokenGenerator;
import com.yihukurama.base.app.utils.EmptyUtil;
import com.yihukurama.base.app.utils.InfoUtil;
import com.yihukurama.base.app.utils.TransferUtils;
import com.yihukurama.base.framework.service.businessservice.ISecurity;
import com.yihukurama.base.framework.web.dto.Request;
import com.yihukurama.base.framework.web.dto.Result;
import com.yihukurama.sysbase.common.config.SystemConfig;
import com.yihukurama.sysbase.common.enums.ResponseEnum;
import com.yihukurama.sysbase.framework.domain.User;
import com.yihukurama.sysbase.framework.domainservice.*;
import com.yihukurama.sysbase.framework.entity.*;
import com.yihukurama.sysbase.framework.mapper.RoleMapper;
import com.yihukurama.sysbase.framework.mapper.UserMapper;
import com.yihukurama.sysbase.framework.mapper.UserroleMapper;
import com.yihukurama.sysbase.sysservice.IPublicApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 说明： 公共api接口实现
 *
 * @Author yihukurama
 * @date: Created in 17:00 2023/12/11
 * @modified: by yihukurama in 17:00 2023/12/11
 */
@Service
public class PublicApiService implements IPublicApi {

    @Autowired
    ISecurity securityService;
    @Autowired
    RedisUtils redisUtils;
    @Autowired
    UserService userService;

    @Autowired
    MenuService menuService;
    @Autowired
    UserroleMapper userroleMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    RoleMapper roleMapper;

    @Autowired
    SystemConfig sysConfig;

    @Autowired
    private RolemenuService rolemenuService;

    @Autowired
    private FuncService funcService;

    @Override
    public Result login(Request<User> request, HttpServletRequest httpRequest) throws TipsException {
        //判断验证码
        String loginUUID = request.getData().getUuid();
        if (EmptyUtil.isEmpty(loginUUID)) {
            return Result.failed("未上传识别码");
        }
        String code = (String) redisUtils.get(loginUUID);
        String loginCode = request.getData().getCode();
        if (EmptyUtil.isEmpty(code) || !code.equals(loginCode)) {
            return Result.failed("验证码错误");
        }

        //获取登录超时时间
        String loginExpiretimeStr = sysConfig.getLoginExpire();
        Long loginExpiretime = Long.valueOf(loginExpiretimeStr);
        User user = request.getData();
        if (user == null || EmptyUtil.isEmpty(user.getUsername()) || EmptyUtil.isEmpty(user.getPassword())) {
            return Result.failed(null, "账户或用户名为空，请检查", ResponseEnum.ERROR_CODE_4005.getCode());
        }
        //密码加密
        String encryptPwd = securityService.pwdEncrypt(user.getPassword());
        user.setPassword(encryptPwd);

        List<UserEntity> userEntitys = userService.list(user);
        if (userEntitys == null || userEntitys.size() != 1) {
            return Result.failed(null, "账号或密码错误，请检查", -1);
        }

        UserEntity userEntity = userEntitys.get(0);
        if (User.STATUS_2.equals(user.getStatus())) {
            return Result.failed(null, "该账号已经禁用", -1);
        }

        //获取用户菜单、角色权限
        UserroleEntity userroleEntity = new UserroleEntity();
        userroleEntity.setUserId(userEntity.getId());
        List<UserroleEntity> userroleEntities = userroleMapper.select(userroleEntity);
        List<MenuEntity> menus = new ArrayList<>();
        List<RoleEntity> roleEntityList = new ArrayList<>();
        for (UserroleEntity entity : userroleEntities) {
            //获取用户角色
            RoleEntity roleEntity = new RoleEntity();
            roleEntity.setId(entity.getRoleId());
            roleEntity = roleMapper.selectByPrimaryKey(roleEntity);
            roleEntityList.add(roleEntity);

            //获取用户可访问菜单
            RolemenuEntity rolemenuEntity = new RolemenuEntity();
            rolemenuEntity.setRoleId(entity.getRoleId());
            List<RolemenuEntity> list = rolemenuService.list(rolemenuEntity);
            for (RolemenuEntity rolemenu : list) {
                MenuEntity menuEntity = new MenuEntity();
                menuEntity.setId(rolemenu.getMenuId());
                MenuEntity load = menuService.load(menuEntity);
                if (load == null) {
                    continue;
                }
                menus.add(load);
            }


        }


        User loginUser = TransferUtils.transferEntity2Domain(userEntity, User.class);
        loginUser.setMenus(menus);
        loginUser.setRoleEntities(roleEntityList);
        //设置token，先删除旧token
        if (!EmptyUtil.isEmpty(loginUser.getToken())) {
            String oldToken = loginUser.getToken();
            redisUtils.remove(oldToken);
        }
        Long timeStamp = System.currentTimeMillis();
        String token = AbstractJwtTokenGenerator.generateToken(loginUser, timeStamp.toString());
        loginUser.setToken(token);
        loginUser.setLoginDate(new Date());

        //获取登录IP
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest httprequest = sra.getRequest();
        loginUser.setLoginIp(InfoUtil.getIpAddr(httprequest));
        loginUser.setUpdateBy(loginUser.getId());


        //不能用userService跟新，否则会进行两次加密
        userMapper.updateByPrimaryKey(loginUser);


        redisUtils.set(Constant.LOGIN_TOKEN_KEY+":"+loginUser.getToken(), loginUser.getId(), loginExpiretime);
        redisUtils.set("online" + loginUser.getId(), loginUser, loginExpiretime);

        loginUser.setCurrentAuthority("user");

        return Result.successed(loginUser, "登录成功");
    }

    @Override
    public Result isLogin(Request<User> request) {
        User user = request.getData();
        if (user == null || EmptyUtil.isEmpty(user.getId())) {
            return Result.failed("参数不能为空");
        }
        if (redisUtils.exists("online" + user.getId())) {
            String uid = user.getId();
            User loginUser = (User) redisUtils.get("online" + uid);
            return Result.successed(loginUser);

        }

        return Result.failed("未登录");
    }

}
